#ifndef packet_pool_h
#define packet_pool_h

#include "cope-packet.h"
#include "packet.h"
//#include "uthash.h"
#include <ext/hash_map>
#include <map>
#include <iostream>
#include <bitset>
#include <list>
#include "virqueue.h"
using std::bitset;
using std::list;
using namespace __gnu_cxx;
#define BITMAP_TOTAL_SIZE 256
#define BITMAP_SIZE 8
class COPE;

typedef struct {
    nsaddr_t srcip; // source ip
    u_int16_t lastpkt; // ip sequence number
    /* u_int16_t pre; // last ip seq number will be expired in next period */
    /* u_int16_t next; // last ip seq number will be expired in next next period */
    u_int16_t shifts; // number of bits shifted
    bitset<BITMAP_TOTAL_SIZE> bitmap; // bit-map of recently heard packets
    /* bool gc; // has done the garbage collection or not */
    /* bitset<256> pre; // bit-map indicates packets will be expired in next period */
    /* bitset<256> next; /\* */
    /* 		       * bit-map indicates packets will be expired */
    /* 		       * in the next next period */
    /* 		       *\/ */
    u_int16_t max;
} report_t;

/* typedef struct { */
/*     int pktid; // packet id */
/*     Packet* ppkt; // pointer to the packet stored in backup_queue_ */
/*     UT_hash_handle hh; // uthash: hash table handler */
/* } pkt_entry_t; */

typedef struct {
    double time;
    Packet* ppkt;
} pkt_entry_t;

typedef list<report_t>::iterator report_iter_t;
typedef list<pkt_entry_t>::iterator pkt_iter_t;

class PacketPool {
 public:
    PacketPool();
    ~PacketPool();

    // operations for hast-table
    void delete_pkt_ht(int pktid);
    Packet* get_packet(int pktid);

    // operations for backup-queue

    
    // operations for report-list
    report_iter_t lookup_node(nsaddr_t srcip);
    hdr_report_t* get_report(nsaddr_t srcip);

    // operations for packet-pool
    ////////////////////////////////////////
    //what if in_pool an encoded packet
    void in_pool(Packet* pkt, COPE* cp);

    void garbage_collection(COPE* cp);

    
    /*
     * The actual queue to store packets, in order of receving time.
     * That means easy to do garbage collection.
     */
    /* list<Packet*> backup_queue_; */
    list<pkt_entry_t> backup_queue_;

    /*
     * A hast table keyed on packet id, then it is fast to get
     * packet when decoding.
     */
    hash_map<int, Packet*> pkt_table_;
    //    pkt_entry_t* pkt_table_;

    /* A list to maintain reception report. */    
    list<report_t> report_list_;

    /*
     * The flag to determine whether the incoming packet will be expired in
     * the next coming period (b_expired_ == 1), otherwise the incoming packet
     * will be expired in the preiod after the next period (b_expired_ == 0).
     * The default value is 1.
     */
    //    bool b_expired_;

    /*
     * pre_pkt_: packet id of the last expired packet in this period
     * next_pkt_: packet id of the last expired packet in the next period
     */
    /* int pre_pkt_; */
    /* int next_pkt_; */

    /* bool b_first_; */
};


#endif
